<template>
  <el-form  :style="formOpt?.formStyle" :model="form" :label-width="formOpt?.labelWidth" ref="formRef">
    <el-row>
      <!-- typeof key === 'string' ? key : '' 只是为了解决ts报错  (key as string)格式化后括号没了 可能是pre的设置问题 -->
      <FormItem v-for="(item, key) in formOpt?.items" :key="key" v-on="itemEmit" :ref="formItemRefFn" v-model="form[key]" :item="item" :itemKey="typeof key === 'string' ? key : ''">
        <template #otherItem="{ item, key }"><slot name="otherItem" :item="item" :key="key"></slot> </template>
        <template #recycleName="data"><slot name="recycleName" v-bind="{ ...data, form }"> </slot></template>
      </FormItem>
      <slot name="otherFormItem" :form="form"> </slot>
      <el-form-item><slot name="otherBtn" :form="form"></slot></el-form-item>
    </el-row>
  </el-form>
</template>
<script lang="ts" setup>
import type { IFormP } from "../index";
import { formEmit, formData } from "@/components/HfForm/form";
import { utilDeepClone } from "@/assets/utils/deepClone";
import type { MessageParamsWithType } from "element-plus";
import { fileType } from "../HfUpload/upload";
const emit = defineEmits([...formEmit]);
const props = defineProps<IFormP>();
const dragStore = useDrag();
const route = useRoute();
const form = ref<{ [key: string]: any }>({});
const formRef = ref();
const formItemRefs = ref<IFormItemEx[]>([]);
let formDate = new formData({ id: props.id, formOpt: props.formOpt, formParams: props.formParams } as IFormP, emit);
const formItemRefFn = (el: any) => {
  let hasItem = formItemRefs.value.find((item) => item === el);
  if (hasItem) return;
  if (el) formItemRefs.value.push(el);
};
async function formValidFn() {
  let valided: boolean = false;
  await formRef.value.validate(async (valid: boolean) => {
    valided = valid;
  });
  return valided;
}
let codePageFormSumitFn = (cformOpteCopy: IPFormFormOpt) => {
  if (route.name !== "coderCreate") return;
  let currentItem: IFormPFormOptItems = {};
  let currentRender = dragStore.renderData.find((item) => {
    return item.id == props.id;
  });
  if (!currentRender || currentRender?.key == "cTable") return;
  currentRender.childrens.map((ite) => {
    currentItem[ite.props.itemKey] = ite.props.item;
  });
  cformOpteCopy.items = currentItem;
};

const submitFormFn = async () => {
  let submitData: any, msge, res;
  if (props.formOpt?.emitBeforeValidSubmit) return emit("emitBeforeValidSubmit", { submitData });
  if (!(await formValidFn())) return;
  try {
    let cformOpteCopy = utilDeepClone(props.formOpt);
    codePageFormSumitFn(cformOpteCopy);
    submitData = ref({ ...form.value, ...props.formOpt?.otherParams });
    Object.keys(submitData.value).forEach((key) => {
      let item = cformOpteCopy.items[key];
      if (!item?.hide && fileType.includes(item?.type as IUploadPType) && !submitData.value[key] && item.hasrules) {
        throw `请上传${item.type == "uVideo" ? "视频" : "图片"}`;
      }
      if (submitData.value[key]?.constructor == Array && !item?.notHandleArray) {
        submitData.value[key] = submitData.value[key].length > 0 && cformOpteCopy.handleToString ? submitData.value[key].join(",") : JSON.stringify(submitData.value[key]);
      }
    });
    emit("emitBeforeSubmit", {
      submitData,
      fn: (msg: string) => {
        msge = msg;
      }
    });
    if (msge) {
      ElMessage.error(msge);
      return;
    }
    let request = props.formOpt.otherRequest || hfoRequest;
    if (cformOpteCopy.saveMethod == "put" || submitData.value.id) {
      let surl = submitData.value.id && props.formOpt?.updateUrl ? cformOpteCopy.updateUrl : cformOpteCopy.saveUrl;
      res = await request.put({ url: surl, data: submitData.value });
    } else {
      let surl = cformOpteCopy.saveUrl;
      res = await request.post({ url: surl, data: submitData.value });
    }
    if (res.statusCode) {
      return res;
    }
  } catch (error) {
    ElMessage.error(error as MessageParamsWithType);
  }
};
const resetfileFn = (e?: any) => {
  form.value = utilDeepClone(e || props.formParams || {});
  for (let item in formItemRefs.value) {
    let key = formItemRefs.value[item].itemKey;
    formItemRefs.value[item].initFormItemFn(form.value[key]);
  }
  formRef.value.clearValidate();
};
const emitHasChange = ({ e, key, item }: IFormItemAChangeRadio) => {
  form.value[key] = e;
  emit("emitHasChange", { e, key, item, form: form.value });
};

const itemEmit = {
  emitOtherGetFile: formDate.formEmitsObj.emitOtherGetFile,
  emitBeforeUpload: formDate.formEmitsObj.emitBeforeUpload,
  emitChangeProps: formDate.formEmitsObj.emitChangeProps,
  emitDeleteValue: formDate.formEmitsObj.emitDeleteValue,
  emitDownTemplate: formDate.formEmitsObj.emitDownTemplate,
  emitHasChange
};
let formExpose: IFormEx = {
  form,
  submitFormFn,
  resetfileFn,
  formRef,
  formValidFn,
  formItemRefs,
  emitHasChange
};
defineExpose({ ...formExpose });
</script>

<style lang="scss">
.formItemTip {
  position: absolute;
  color: #f00;
  font-size: 12px;
  bottom: -25px;
  left: 0;
  width: max-content;
  z-index: 111;
}

.el-form--inline {
  max-width: 1300px;
}

.el-form {
  .el-form-item {
    position: relative;
  }
}

.el-popper {
  z-index: 2600 !important;
}
</style>
